package xj.graph2d.tools;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Observer;

import xj.graph2d.Command;
import xj.graph2d.DrawAttr;
import xj.graph2d.DrawCanvas;
import xj.graph2d.DrawShape;
import xj.graph2d.DrawShapeConstants;
import xj.graph2d.DrawShapeFactory;
import xj.graph2d.command.AddShapeCommand;
import xj.graph2d.shapes.ScribbleShape;

public class ScribbleTool extends SimpleDrawTool {

  public ScribbleTool() {
    this(null, DrawShapeConstants.USE_SYSTEM_DRAW_ATTR);
  }

  public ScribbleTool(int cloneDrawAttrMode) {
    this(null, cloneDrawAttrMode);
  }

  public ScribbleTool(ScribbleShape proto) {
    this(proto, DrawShapeConstants.USE_SYSTEM_DRAW_ATTR);
  }

  public ScribbleTool(ScribbleShape proto, int cloneDrawAttrMode) {
    super(cloneDrawAttrMode);
    if (proto != null) {
      this.proto = proto;
    } else {
      this.proto = new ScribbleShape();
    }
  }

  @Override
  public void mouseLButtonPressed(Observer observer, Point p, int modifiers) {
    mouseButtonDown = true;
    start(observer);
    if (view != null) {

      view.displayHelpMessage(MSGKEY_1);

      Graphics2D g2 = canvas.getGraphics2D();
      canvas.setTransform(g2);
      DrawShape selected = doc.getSelectedShape();
      doc.setSelectedShape(null);
      canvas.repaintShape(selected);
      canvas.setEditingMode(true);
      prev = view.physicalToVirtual(p);
      shape = (ScribbleShape) DrawShapeFactory.cloneDrawShape(proto, view,
	  cloneDrawAttrMode);
      shape.appendPoint(prev);
      g2.dispose();
    }
  }

  @Override
  public void mouseDragged(Observer observer, Point p, int modifiers) {
    if (mouseButtonDown && view != null) {

      displayLocation(p);

      Graphics2D g2 = canvas.getGraphics2D();
      canvas.setTransform(g2);
      DrawAttr attr = view.getDrawAttr();
      if (attr != null) {
	g2.setColor(attr.getPenColor());
      }
      Point2D cur = view.physicalToVirtual(p);
      g2.draw(new Line2D.Float(prev, cur));
      shape.appendPoint(cur);
      prev = cur;
      g2.dispose();
    }
  }

  @Override
  public void mouseLButtonReleased(Observer observer, Point p, int modifiers) {
    if (mouseButtonDown && view != null) {
      DrawCanvas canvas = view.getCanvas();
      canvas.setEditingMode(false);
      shape.calculateBounds();
      Rectangle2D r = shape.getBounds();

      if (r.getWidth() >= 1 && r.getHeight() >= 1) {
	canvas.repaintRect(r);
	Command cmd = new AddShapeCommand(view, doc, shape);
	doc.executeCommand(cmd);
      }

      //
      // doc.add(shape, true);
      // canvas.repaintShape(shape);
    }
    mouseButtonDown = false;
  }

  @Override
  public void mouseRButtonPressed(Observer observer, Point p, int modifiers) {
    start(observer);
    if (view != null) {
      Graphics2D g2 = canvas.getGraphics2D();

      DrawShape prevSelectedShape = doc.getSelectedShape();
      if (prevSelectedShape != null) {
	doc.setSelectedShape(null);
	canvas.repaintShape(prevSelectedShape, true);
      }

    }

  }

  protected ScribbleShape shape;

  protected ScribbleShape proto;

  protected static final String MSGKEY_1 = "ScribbleTool.message.1";

}
